home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / GLE / candlestick.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  11.4 KB  |  425 lines

  1.  
  2. /* 
  3.  * candlestick.c
  4.  * 
  5.  * FUNCTION:
  6.  * Draws a skewed candlestick shape using the Lathe primitive
  7.  *
  8.  * HISTORY:
  9.  * -- created by Linas Vepstas October 1991
  10.  * -- C++ and OO playing around Linas Vepstas June 1993
  11.  * -- converted to use GLUT -- December 1995, Linas
  12.  *
  13.  */
  14.  
  15. /* required include files */
  16. #include <stdlib.h>
  17. #include <math.h>
  18. #include <GL/glut.h>
  19. #include <GL/tube.h>
  20.  
  21. /* Some <math.h> files do not define M_PI... */
  22. #ifndef M_PI
  23. #define M_PI 3.14159265358979323846
  24. #endif
  25.  
  26. /* =========================================================== */
  27.  
  28. #define SET_RGB(rgb,r,g,b) {            \
  29.     rgb[0]=r; rgb[1]=g; rgb[2]=b;        \
  30.  
  31. typedef struct _material {
  32.  
  33.    /* public data areas */
  34.    float emission[3];    
  35.    float ambient[3];  
  36.    float diffuse[3];  
  37.    float specular[3]; 
  38.    float shininess;
  39.  
  40. } Material;
  41.  
  42. #define SET_EMIS(self,r,g,b) { SET_RGB(self->emission, r,g,b); }
  43. #define SET_AMB(self,r,g,b) { SET_RGB(self->ambient, r,g,b); }
  44. #define SET_DIFF(self,r,g,b) { SET_RGB(self->diffuse, r,g,b); }
  45. #define SET_SPEC(self,r,g,b) { SET_RGB(self->specular, r,g,b); }
  46.  
  47. /* =========================================================== */
  48.  
  49. #ifdef NOTNOW
  50. class goPolyline {
  51.    public:
  52.       int dimension;
  53.       int numPoints;
  54.       double * pts;
  55.  
  56.    private:
  57.       int  nfree;
  58.  
  59.    public:
  60.       goPolyline ();        // by default, construct 3D polyline
  61.       goPolyline (int);            // construct arbitrary dimension polyline
  62.       void Print ();
  63.       void AddPoint (double x, double y);
  64.       void AddNormal (double x, double y);
  65.       void MakeFacetNormal ();
  66. };
  67. #endif /* NOTNOW */
  68.  
  69. typedef double SVec[2];
  70.  
  71. typedef struct contour {
  72.  
  73.    /* public data areas */
  74.    int numContourPoints;
  75.    int numContourNorms;
  76.    SVec * pts;
  77.    SVec * norms;
  78.    double up[3];
  79.  
  80. } Contour;
  81.  
  82. #define pfree numContourPoints
  83. #define nfree numContourNorms
  84.  
  85. #define NEW_CONTOUR(self) {            \
  86.    self -> pts = (SVec *) malloc (100*sizeof (double));    \
  87.    self -> norms = (SVec *) malloc (100*sizeof (double));    \
  88.    self -> pfree = 0;        \
  89.    self -> nfree = 0;        \
  90. }
  91.  
  92. #define ADD_POINT(self,x,y) {             \
  93.    self -> pts[self->pfree][0] = x;        \
  94.    self -> pts[self->pfree][1] = y;        \
  95.    self->pfree ++;                \
  96. }
  97.  
  98. #define ADD_NORMAL(self,x,y) {             \
  99.    self -> norms[self->nfree][0] = x;        \
  100.    self -> norms[self->nfree][1] = y;        \
  101.    self->nfree ++;                \
  102. }
  103.  
  104. #define MAKE_NORMAL(self) {            \
  105.    float dx, dy, w;                \
  106.    dx = self -> pts [self->pfree -1][0];    \
  107.    dx -= self -> pts [self->pfree -2][0];    \
  108.    dy = self -> pts [self->pfree -1][1];    \
  109.    dy -= self -> pts [self->pfree -2][1];    \
  110.    w = 1.0 / sqrt (dx*dx+dy*dy);        \
  111.    dx *= w;                    \
  112.    dy *= w;                    \
  113.    self -> norms[self->nfree][0] = -dy;        \
  114.    self -> norms[self->nfree][1] = dx;        \
  115.    self -> nfree ++;                \
  116. }
  117.  
  118. /* =========================================================== */
  119. /* class gleExtrustion */
  120.  
  121. typedef struct _extrusion {
  122.    Material    *material;    /* material description */
  123.    Contour     *contour;    /* 2D contour */
  124.  
  125.    double radius;        /* for polycylinder, torus */
  126.    double startRadius;     /* spiral starts in x-y plane */
  127.    double drdTheta;        /* change in radius per revolution */
  128.    double startZ;          /* starting z value */
  129.    double dzdTheta;        /* change in Z per revolution */
  130.    double startXform[2][3]; /* starting contour affine xform */
  131.    double dXdTheta[2][3]; /* tangent change xform per revoln */
  132.    double startTheta;      /* start angle in x-y plane */
  133.    double sweepTheta;     /* degrees to spiral around */
  134.  
  135. } Extrusion;
  136.  
  137. #define  NEW_EXTRUSION(self) {        \
  138.    self -> material = (Material *) malloc (sizeof (Material));    \
  139.    self -> contour = (Contour *) malloc (sizeof (Contour));    \
  140.    NEW_CONTOUR (self->contour);                    \
  141. }
  142.     
  143.  
  144. /* =========================================================== */
  145. Extrusion *candle = NULL;
  146.  
  147. /* =========================================================== */
  148. float lastx=0;
  149. float lasty=0;
  150.  
  151. void draw_candle (void) {
  152.  
  153.    /* attach the mouse */
  154.    candle->dzdTheta = - 0.015 * (lasty -150.0);
  155.  
  156. /* rotational delta sine & cosines from mouse */
  157. /* disable twist -- confusing to the viewer, hard to explain */
  158. /*
  159.    mouse -> AttachMouseYd (mouse, 0.0004, -0.1, &candle->dXdTheta[0][1]);
  160. */
  161.    glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, candle->material->ambient);
  162.    glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, candle->material->diffuse);
  163.    glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, candle->material->specular);
  164.    glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 2.0);
  165.  
  166. #ifdef IBM_GL_32
  167.    rotate (-750, 'x');
  168.    rotate (-1050, 'z');
  169.    translate (-0.5, -0.5, -0.5);
  170.  
  171.    lathe (candle->contour->numContourPoints,
  172.            candle->contour->pts,
  173.            candle->contour->norms,
  174.            candle->contour->up,
  175.            candle->startRadius,    /* donut radius */
  176.            candle->drdTheta,   /* change in donut radius per revolution */
  177.            candle->startZ,    /* start z value */
  178.            candle->dzdTheta,     /* change in Z per revolution */
  179.            candle->startXform, 
  180.            candle->dXdTheta,
  181.            candle->startTheta,     /* start angle */
  182.            candle->sweepTheta);     /* sweep angle */
  183. #endif
  184.  
  185.  
  186. #define OPENGL_10
  187. #ifdef OPENGL_10
  188.    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  189.  
  190.    /* set up some matrices so that the object spins with the mouse */
  191.    glPushMatrix ();
  192.    glTranslatef (0.0, 0.0, -80.0);
  193.    glRotated (-75.0, 1.0, 0.0, 0.0);
  194.    glRotated (-105.0, 0.0, 0.0, 1.0);
  195.  
  196.    glEnable (GL_LIGHTING);
  197.    gleLathe (candle->contour->numContourPoints,
  198.            candle->contour->pts,
  199.            candle->contour->norms,
  200.            candle->contour->up,
  201.            candle->startRadius,    /* donut radius */
  202.            candle->drdTheta,   /* change in donut radius per revolution */
  203.            candle->startZ,    /* start z value */
  204.            candle->dzdTheta,     /* change in Z per revolution */
  205.            candle->startXform, 
  206.            candle->dXdTheta,
  207.            candle->startTheta,     /* start angle */
  208.            candle->sweepTheta);     /* sweep angle */
  209.  
  210.    glDisable (GL_LIGHTING);
  211.  
  212.    glPopMatrix ();
  213.    glutSwapBuffers ();
  214. #endif 
  215. }
  216.  
  217. /* =========================================================== */
  218.  
  219. #define SCALE 1.0
  220. #define PT(x,y) { ADD_POINT (candle->contour, SCALE*x, SCALE*y); }
  221. #define NORM(x,y) { ADD_NORMAL (candle->contour, x, y); }
  222. #define FACET { MAKE_NORMAL (candle->contour); }
  223.  
  224. /* =========================================================== */
  225.  
  226. void init_candle (void)
  227. {
  228.    int j;
  229.    double theta, dtheta;
  230.    int style;
  231.  
  232.    candle = (Extrusion *) malloc (sizeof (Extrusion));
  233.    NEW_EXTRUSION (candle);
  234.  
  235.    /* define candle color */
  236.    SET_AMB (candle->material, 0.25, 0.25, 0.25);
  237.    SET_DIFF (candle->material, 0.8, 0.6, 0.175);
  238.    SET_SPEC (candle->material, 0.45, 0.45, 0.45);
  239.  
  240.    /* define lathe/spiral parameters */
  241.    candle -> startRadius = 1.5;
  242.    candle -> drdTheta = 0.0;
  243.    candle -> startZ = 0.0;
  244.    candle -> dzdTheta = 0.0;
  245.    candle -> startTheta = 0.0;
  246.    candle -> sweepTheta = 360.0;
  247.  
  248.    /* initialize contour up vector */
  249.    candle->contour->up[0] = 1.0;
  250.    candle->contour->up[1] = 0.0;
  251.    candle->contour->up[2] = 0.0;
  252.  
  253.    /* define candlestick contour */
  254.    PT (-8.0, 0.0); 
  255.    PT (-10.0, 0.0); FACET; 
  256.    PT (-10.0, 2.0); FACET;
  257.    PT (-9.6, 2.0); FACET;
  258.    PT (-8.0, 0.0); FACET;
  259.    PT (-5.8, 0.0); FACET;
  260.    PT (-5.2, 0.6); FACET;
  261.    PT (-4.6, 0.0); FACET;
  262.    PT (-1.5, 0.0); FACET;
  263.  
  264.    dtheta = M_PI /14.0;
  265.    theta = 0.0;
  266.    for (j=0; j<14; j++) {
  267.       PT ((-1.5*cos(theta)) , (1.5*sin(theta)));
  268.       NORM ((-cos(theta)) , sin(theta));
  269.       theta += dtheta;
  270.    }
  271.    PT (1.5, 0.0); FACET; 
  272.    PT (4.6, 0.0); FACET;
  273.    PT (5.2, 0.6); FACET;
  274.    PT (5.8, 0.0); FACET;
  275.    PT (7.0, 0.0); FACET;
  276.    PT (7.5, 0.2); FACET;
  277.    PT (8.0, 0.8); FACET;
  278.    PT (8.3, 0.9); FACET;
  279.    PT (8.15, 1.8); FACET;
  280.    PT (8.8, 2.8); FACET;
  281.    PT (9.2, 3.8); FACET;
  282.    PT (9.5, 3.8); FACET;
  283.    PT (9.56, 3.75); FACET;
  284.    PT (9.62, 3.75); FACET;
  285.    PT (9.7, 3.8); FACET; 
  286.    PT (10.0, 3.8); FACET;
  287.    PT (10.0, 0.0); FACET;
  288.    PT (7.0, 0.0); FACET;
  289.  
  290.    /* initialize the transofrms */
  291.    candle->startXform[0][0] = 1.0;
  292.    candle->startXform[0][1] = 0.0;
  293.    candle->startXform[0][2] = 0.0;
  294.    candle->startXform[1][0] = 0.0;
  295.    candle->startXform[1][1] = 1.0;
  296.    candle->startXform[1][2] = 0.0;
  297.  
  298.    candle->dXdTheta[0][0] = 0.0;
  299.    candle->dXdTheta[0][1] = 0.0;
  300.    candle->dXdTheta[0][2] = 0.0;
  301.    candle->dXdTheta[1][0] = 0.0;
  302.    candle->dXdTheta[1][1] = 0.0;
  303.    candle->dXdTheta[1][2] = 0.0;
  304.  
  305.    /* set the initial join style */
  306.    style = gleGetJoinStyle ();
  307.    style &= ~TUBE_NORM_MASK;
  308.    style |= TUBE_NORM_PATH_EDGE;
  309.    style |= TUBE_NORM_FACET;
  310.    gleSetJoinStyle (style);
  311.  
  312. }
  313.  
  314. /* =========================================================== */
  315.  
  316. /* get notified of mouse motions */
  317. void MouseMotion (int x, int y)
  318. {
  319.    lastx = x;
  320.    lasty = y;
  321.    glutPostRedisplay ();
  322. }
  323.  
  324. void JoinStyle (int msg) 
  325. {
  326.    int style;
  327.    /* get the current joint style */
  328.    style = gleGetJoinStyle ();
  329.  
  330.    /* there are four different join styles, 
  331.     * and two different normal vector styles */
  332.    switch (msg) {
  333.  
  334.       case 20:
  335.          style &= ~TUBE_NORM_MASK;
  336.          style |= TUBE_NORM_FACET;
  337.          break;
  338.       case 21:
  339.          style &= ~TUBE_NORM_MASK;
  340.          style |= TUBE_NORM_EDGE;
  341.          break;
  342.       case 22:
  343.          style &= ~TUBE_NORM_MASK;
  344.          style |= TUBE_NORM_PATH_EDGE;
  345.          style |= TUBE_NORM_FACET;
  346.          break;
  347.       case 23:
  348.          style &= ~TUBE_NORM_MASK;
  349.          style |= TUBE_NORM_PATH_EDGE;
  350.          style |= TUBE_NORM_EDGE;
  351.          break;
  352.  
  353.       case 99:
  354.          exit (0);
  355.  
  356.       default:
  357.          break;
  358.    }
  359.    gleSetJoinStyle (style);
  360.    glutPostRedisplay ();
  361. }
  362.  
  363. /* set up a light */
  364. GLfloat lightOnePosition[] = {40.0, 40, 100.0, 0.0};
  365. GLfloat lightOneColor[] = {0.54, 0.54, 0.54, 1.0}; 
  366.  
  367. GLfloat lightTwoPosition[] = {-40.0, 40, 100.0, 0.0};
  368. GLfloat lightTwoColor[] = {0.54, 0.54, 0.54, 1.0}; 
  369.  
  370. int
  371. main (int argc, char * argv[]) {
  372.  
  373.    /* initialize glut */
  374.    glutInit (&argc, argv);
  375.    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  376.    glutCreateWindow ("candlestick");
  377.    glutDisplayFunc (draw_candle);
  378.    glutMotionFunc (MouseMotion);
  379.  
  380.    /* create popup menu */
  381.    glutCreateMenu (JoinStyle);
  382.    glutAddMenuEntry ("Facet Normal Vectors", 20);
  383.    glutAddMenuEntry ("Edge Normal Vectors", 21);
  384.    glutAddMenuEntry ("Facet Sweep Normal Vectors", 22);
  385.    glutAddMenuEntry ("Edge Sweep Normal Vectors", 23);
  386.    glutAddMenuEntry ("------------------", 9999);
  387.    glutAddMenuEntry ("Exit", 99);
  388.    glutAttachMenu (GLUT_MIDDLE_BUTTON);
  389.  
  390.    /* initialize GL */
  391.    glClearDepth (1.0);
  392.    glEnable (GL_DEPTH_TEST);
  393.    glClearColor (0.0, 0.0, 0.0, 0.0);
  394.    glShadeModel (GL_SMOOTH);
  395.  
  396.    glMatrixMode (GL_PROJECTION);
  397.    /* roughly, measured in centimeters */
  398.    glFrustum (-9.0, 9.0, -9.0, 9.0, 50.0, 150.0);
  399.    glMatrixMode(GL_MODELVIEW);
  400.  
  401.    /* initialize lighting */
  402.    glLightfv (GL_LIGHT0, GL_POSITION, lightOnePosition);
  403.    glLightfv (GL_LIGHT0, GL_AMBIENT, lightOneColor);
  404.    glLightfv (GL_LIGHT0, GL_DIFFUSE, lightOneColor);
  405.    glLightfv (GL_LIGHT0, GL_SPECULAR, lightOneColor);
  406.    glEnable (GL_LIGHT0);
  407.    glLightfv (GL_LIGHT1, GL_POSITION, lightTwoPosition);
  408.    glLightfv (GL_LIGHT1, GL_DIFFUSE, lightTwoColor);
  409.    glLightfv (GL_LIGHT1, GL_AMBIENT, lightTwoColor);
  410.    glEnable (GL_LIGHT1);
  411.    glEnable (GL_LIGHTING);
  412.    glEnable (GL_NORMALIZE);
  413.    /* glColorMaterial (GL_FRONT_AND_BACK, GL_DIFFUSE); */
  414.    /* glEnable (GL_COLOR_MATERIAL); */
  415.  
  416.    init_candle ();
  417.  
  418.    glutMainLoop ();
  419.    return 0;             /* ANSI C requires main to return int. */
  420. }
  421.  
  422. /* ===================== END OF FILE ================== */
  423.  
  424.